from optparse import OptionParser
import ConfigParser
import os
from bettybox.storage.EvernoteStorage import EvernoteStorage
from bettybox.Ocr import Ocr
from bettybox.Document import Document
from bettybox.agent.EDFAgent import EDFAgent
from bettybox.agent.CESUAgent import CESUAgent
from util import get_class

class BettyBox(object):
  
  def __init__(self):
    self.__agents = []
    self.__ocr = None
    self.__storage = None

  def set_OCR(self, ocr):
    self.__ocr = ocr
  
  def set_storage(self, storage):
    self.__storage = storage
    
  def add_agent(self, agent):
    self.__agents += [ agent ]
  
  def scan(self, rootdir):
    for root, dirs, files in os.walk(rootdir):
      for file in filter(lambda x: x.endswith('.pdf'), files):
        f = os.path.join(root, file)
        print "Scan file: ", f
        self.send(f)

  def send(self, file):
    doc = Document()
    doc.title = file.split('/')[-1][:-4]
    doc.attachment = file
    self.send_document(doc)

  def send_document(self, doc, cb=None):
    if not self.__storage.Contains(doc.title):
      words = self.analyze(doc.attachment)
      doc.wordIndex = words
      self.__storage.Store(doc)
      if not cb is None:
        cb("Done")
    else:
      cb("Done")

  def analyze(self, file):
    if self.__ocr is None:
      return []
    else:
      return self.__ocr.analyze(file)
    
  def collect(self):
    for agent in self.__agents:
      print "Running agent: ", agent
      #self.__agent.Connect()
      for doc in agent.Collect():
        if not self.__storage.Contains(doc.title):
          doc.wordIndex = self.analyze(doc.attachment)
          self.__storage.Store(doc)
  

class BettyBoxConfigurator(object):

  def __init__(self):
    pass

  def get_betty(self, config_file):
    bettybox = BettyBox()
  
    # read config file
    config = ConfigParser.RawConfigParser()
    config.read(config_file)

    # create and set OCR
    if config.get('CONFIG', 'ocr') == 'True':
      bettybox.set_OCR(Ocr(
        config.get('OCR', 'tesseract'),
        config.get('OCR', 'ghostscript'),
        config.get('OCR', 'lang')))

    # create and set storage
    (storage_type, storage_host, storage_user, storage_pwd) = (
        config.get('STORAGE', 'type'),
        config.get('STORAGE', 'host'),
        config.get('STORAGE', 'user'),
        config.get('STORAGE', 'password')
         )
    storage = get_class(storage_type)(storage_host, storage_user, storage_pwd)
    storage.Connect()
    bettybox.set_storage(storage)

    agent_config = ConfigParser.RawConfigParser()
    agent_config.read(config.get('CONFIG', 'agent.config'))
    agents = agent_config.sections()
    for name in agents:
      print "Configuring agent: ", name
      agent_cls = get_class(agent_config.get(name, 'agent'))
      agent = agent_cls(agent_config.get(name, 'user'), agent_config.get(name, 'password'))
      bettybox.add_agent(agent)

    return bettybox


def main():
  parser = OptionParser(usage="Usage: %prog [options]")
  parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=True, help="Print lots of debug messages")
  parser.add_option("-c", "--config", dest="config", default="config.txt", help="Configuration file")
  parser.add_option("-m", "--mode", dest="mode", default="scan", help="Interaction mode ['scan', 'agent']")
  parser.add_option("-a", "--agent", dest="agent", default=None, help="Agent name, run all agents if not specified")
  parser.add_option("-d", "--directory", dest="directory", default=".", help="Directory to scan if 'scan' mode is specified")
  (option, args) = parser.parse_args()

  if option.verbose:
    # TODO: configure logging to DEBUG
    pass

  if option.mode == 'scan':
    pass
  elif option.mode == 'agent':
    pass
  else:
    parser.error("You must set mode to a valid mode: ['scan', 'agent']")
  
  config_file = option.config

  configurator = BettyBoxConfigurator()
  bettybox = configurator.get_betty(config_file)

  # Scan mode
  if option.mode == 'scan':
    bettybox.scan(option.directory)
  # Agent mode
  elif option.mode == 'agent':
    bettybox.collect()
  

if __name__ == '__main__':
  main()
  
